
#include <stdlib.h>
#include <stdio.h>

#include "graf.h"

int main(int argc, char** argv) 
{
	if (argc < 4) 
	{
		printf("usage: study threshold adjlist_out degrees_out ids_out\n");
        exit(0);
	}

    char* in_name = argv[1];
    float rth = atof(argv[2]);
    char* out_name = argv[3];
    char* degrees_name = argv[4];
    char* ids_name = argv[5];

	FILE* fpin = fopen(in_name, "rb");
	FILE* fpout = fopen(out_name, "wb");

	unsigned int ni;
	unsigned int nj;
	unsigned int nk;
	unsigned int nt;

	fread(&ni, sizeof(unsigned int), 1, fpin);
	fread(&nj, sizeof(unsigned int), 1, fpin);
	fread(&nk, sizeof(unsigned int), 1, fpin);
	fread(&nt, sizeof(unsigned int), 1, fpin);

	printf("epi is %dx%dx%dx%d\n", ni, nj, nk, nt);

	int ninjnk = ni*nj*nk;
	int njnk = nj*nk;

	unsigned int num_vertices;
	unsigned int num_edges;

	fread(&num_vertices, sizeof(unsigned int), 1, fpin);
	fread(&num_edges, sizeof(unsigned int), 1, fpin);

	printf("num_vertices=%d num_edges=%d\n", num_vertices, num_edges);

	unsigned int* degrees = (unsigned int*) calloc(ninjnk, sizeof(unsigned int));
	unsigned int* idsp = (unsigned int*) malloc(ninjnk * sizeof(unsigned int));
	int* ids = (int*) malloc(ninjnk * sizeof(int));

	for (unsigned int i = 0; i < ninjnk; i++)
	{
		ids[i] = -1;
	}

	int num_vertices_selected = 0;
	int num_edges_selected = 0;

	printf("writing adj list\n");

	fseek(fpout, 8, SEEK_SET);

	for (unsigned int i = 0; i < num_edges; i++)
	{
		unsigned int n1;
		unsigned int n2;
		float r;

		fread(&n1, sizeof(unsigned int), 1, fpin);
		fread(&n2, sizeof(unsigned int), 1, fpin);
		fread(&r, sizeof(float), 1, fpin);

		if ((r < rth) && (r > -rth)) continue;

		num_edges_selected++;

		if (ids[n1] < 0) 
		{
			ids[n1] = num_vertices_selected;
			idsp[num_vertices_selected] = n1;
			num_vertices_selected++;
		}

		degrees[ids[n1]]++;

		if (ids[n2] < 0) 
		{
			ids[n2] = num_vertices_selected;
			idsp[num_vertices_selected] = n2;
			num_vertices_selected++;
		}

		degrees[ids[n2]]++;

		fwrite(ids+n1, sizeof(unsigned int), 1, fpout);
		fwrite(ids+n2, sizeof(unsigned int), 1, fpout);

	}

	printf("num_vertices_selected=%d num_edges_selected=%d\n", num_vertices_selected, num_edges_selected);

	fseek(fpout, 0, SEEK_SET);
	fwrite(&num_vertices_selected, sizeof(unsigned int), 1, fpout);
	fwrite(&num_edges_selected, sizeof(unsigned int), 1, fpout);

	fclose(fpin);
	fclose(fpout);

	free(ids);

	printf("writing ids and degrees\n");

	FILE* fpdegrees = fopen(degrees_name, "w");
	FILE* fpids = fopen(ids_name, "w");

	fprintf(fpdegrees, "%d %d %d %d\n", num_vertices, ni, nj, nk);
	fprintf(fpids, "%d %d %d %d\n", num_vertices, ni, nj, nk);

	for (int v = 0; v < num_vertices; v++) 
	{
		unsigned int index = idsp[v];

		unsigned int i = index / njnk;
		unsigned int j = (index - i * njnk) / nk;
		unsigned int k = (index - i * njnk - j * nk);

		fprintf(fpdegrees, "%d %d\n", index, degrees[v]);
		fprintf(fpids, "%d %d %d %d\n", index, i, j, k);
	}

	fclose(fpids);
	fclose(fpdegrees);

	free(idsp);
	free(degrees);
}
